
    /*
    ===============================================================================================================================================
    ===== WARRNING: THE FOLLOWING CODE IS AUTO GENERATED, DO NOT MODIFY THIS CODE! EXTEND THIS CODE BY USING PARTIAL CLASSES AND SUB CLASSES. =====
    ===============================================================================================================================================
    */

    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Threading;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using System.Threading.Tasks;
    
      namespace NOAA.Contracts.Weather.V1
      {
      using Messages;
      using Faults;
      using Interfaces;
      using Services;
      using Aspects;

      public static class Namespaces
      {
      public const string XmlService = "http://services.noaa.gov/Weather/V1";
      public const string XmlSchema = "http://services.noaa.gov/Weather/V1#data";
      public const string ClrRoot = "NOAA.Contracts.Weather.V1";
      public const string ClrModels = ClrRoot + ".Models";
      public const string ClrMessages = ClrRoot + ".Messages";
      }

      namespace Messages
      {

      [DataContract(Name="WeatherServiceRequest", Namespace=Namespaces.XmlSchema)]
      public partial class WeatherServiceRequest 
      { }

      [DataContract(Name="BatchWeatherServiceRequest", Namespace=Namespaces.XmlSchema)]
      public partial class BatchWeatherServiceRequest
      {
      [DataMember(Name="Requests", IsRequired=true)]
      public IDictionary<string, WeatherServiceRequest> Requests { get; set; }
      }

      
        [DataContract(Name="GetForcastRequest", Namespace=Namespaces.XmlSchema)]
        public partial class GetForcastRequest : WeatherServiceRequest { }
      
        [DataContract(Name="GetCurrentTemperatureRequest", Namespace=Namespaces.XmlSchema)]
        public partial class GetCurrentTemperatureRequest : WeatherServiceRequest { }
      
        [DataContract(Name="GetTemperatureHistoryRequest", Namespace=Namespaces.XmlSchema)]
        public partial class GetTemperatureHistoryRequest : WeatherServiceRequest { }
      

      [DataContract(Name="WeatherServiceResponse", Namespace=Namespaces.XmlSchema)]
      public partial class WeatherServiceResponse  
      { }

      [DataContract(Name="BatchWeatherServiceResponse", Namespace=Namespaces.XmlSchema)]
      public partial class BatchWeatherServiceResponse
      {
      [DataMember(Name="Responses", IsRequired=true)]
      public IDictionary<string, WeatherServiceResponse> Responses { get; set; }

      [DataMember(Name="Faults", IsRequired=true)]
      public IDictionary<string, WeatherServiceFault> Faults { get; set; }
      }

      
        [DataContract(Name="GetForcastResponse", Namespace=Namespaces.XmlSchema)]
        public partial class GetForcastResponse : WeatherServiceResponse { }
      
        [DataContract(Name="GetCurrentTemperatureResponse", Namespace=Namespaces.XmlSchema)]
        public partial class GetCurrentTemperatureResponse : WeatherServiceResponse { }
      
        [DataContract(Name="GetTemperatureHistoryResponse", Namespace=Namespaces.XmlSchema)]
        public partial class GetTemperatureHistoryResponse : WeatherServiceResponse { }
      
      }

      namespace Faults
      {
      [DataContract(Name="WeatherServiceFault", Namespace=Namespaces.XmlSchema)]
      public partial class WeatherServiceFault 
      { }

      
        [DataContract(Name="GetForcastFault", Namespace=Namespaces.XmlSchema)]
        public partial class GetForcastFault : WeatherServiceFault { }
      
        [DataContract(Name="GetCurrentTemperatureFault", Namespace=Namespaces.XmlSchema)]
        public partial class GetCurrentTemperatureFault : WeatherServiceFault { }
      
        [DataContract(Name="GetTemperatureHistoryFault", Namespace=Namespaces.XmlSchema)]
        public partial class GetTemperatureHistoryFault : WeatherServiceFault { }
      
      }

      namespace Interfaces
      {
        
        [ServiceContract(Name="WeatherService", Namespace=Namespaces.XmlService)]
        public partial interface IWeatherService
        {
        
          [FaultContract(typeof(GetForcastFault))]
          [OperationContract(Name="GetForcast")]
          GetForcastResponse GetForcast(GetForcastRequest request);
        
          [FaultContract(typeof(GetCurrentTemperatureFault))]
          [OperationContract(Name="GetCurrentTemperature")]
          GetCurrentTemperatureResponse GetCurrentTemperature(GetCurrentTemperatureRequest request);
        
          [FaultContract(typeof(GetTemperatureHistoryFault))]
          [OperationContract(Name="GetTemperatureHistory")]
          GetTemperatureHistoryResponse GetTemperatureHistory(GetTemperatureHistoryRequest request);
        
        }

        [ServiceContract(Name="BatchWeatherService", Namespace=Namespaces.XmlService)]
        public partial interface IBatchWeatherService
        {
        [FaultContract(typeof(WeatherServiceFault))]
        [OperationContract(Name="Process")]
        BatchWeatherServiceResponse Process(BatchWeatherServiceRequest request);
        }
        
        public partial interface IWeatherServiceClient
        {
          IWeatherService Service { get; set; }
        }
      }

      namespace Tests
      {
      
        [TestClass]
        public partial class GetForcastTest
        {
        private GetForcastRequest request;
        private GetForcastResponse response;
        private IWeatherService service;

        [TestInitialize]
        public void TestInitialize()
        {
        request = new GetForcastRequest();
        service = new MockWeatherService();
        response = service.GetForcast(request);
        }

        [TestMethod]
        public void ResponseIsNotNull()
        {
        Assert.IsNotNull(response);
        }

        [TestMethod]
        public void ResponseTypeIsGetForcastResponse()
        {
        Assert.IsInstanceOfType(response, typeof(GetForcastResponse));
        }

        }
      
        [TestClass]
        public partial class GetCurrentTemperatureTest
        {
        private GetCurrentTemperatureRequest request;
        private GetCurrentTemperatureResponse response;
        private IWeatherService service;

        [TestInitialize]
        public void TestInitialize()
        {
        request = new GetCurrentTemperatureRequest();
        service = new MockWeatherService();
        response = service.GetCurrentTemperature(request);
        }

        [TestMethod]
        public void ResponseIsNotNull()
        {
        Assert.IsNotNull(response);
        }

        [TestMethod]
        public void ResponseTypeIsGetCurrentTemperatureResponse()
        {
        Assert.IsInstanceOfType(response, typeof(GetCurrentTemperatureResponse));
        }

        }
      
        [TestClass]
        public partial class GetTemperatureHistoryTest
        {
        private GetTemperatureHistoryRequest request;
        private GetTemperatureHistoryResponse response;
        private IWeatherService service;

        [TestInitialize]
        public void TestInitialize()
        {
        request = new GetTemperatureHistoryRequest();
        service = new MockWeatherService();
        response = service.GetTemperatureHistory(request);
        }

        [TestMethod]
        public void ResponseIsNotNull()
        {
        Assert.IsNotNull(response);
        }

        [TestMethod]
        public void ResponseTypeIsGetTemperatureHistoryResponse()
        {
        Assert.IsInstanceOfType(response, typeof(GetTemperatureHistoryResponse));
        }

        }
      
      }

      namespace Aspects
      {
        [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
        public abstract class WeatherServiceAspect : Attribute
        {
          public int Order { get; set; }
          protected WeatherServiceAspect(int order) { Order = order; }
          public virtual void OnPreWeatherServiceOperation(ref WeatherServiceRequest request) { }
          public virtual void OnPostWeatherServiceOperation(ref WeatherServiceRequest request, ref WeatherServiceResponse response) { }
          public virtual void OnWeatherServiceOperationError(ref WeatherServiceRequest request, ref Exception exception) { }
        } 
      }

      namespace Services
      {

      /*

      For .svc file:

      <%@ ServiceHost Language="C#" Debug="true" Service="NOAA.Contracts.Weather.V1.Services.MockWeatherService" %>

      For web.config, serviceModel section:

      <service name="NOAA.Contracts.Weather.V1.Services.MockWeatherService">
      <endpoint bindingNamespace="http://services.noaa.gov/Weather/V1"
      binding="basicHttpBinding"
      contract="NOAA.Contracts.Weather.V1.Interfaces.IWeatherService"/>
      </service>
      */

      [ServiceBehavior(Name = "WeatherService", Namespace = Namespaces.XmlService)]
      public partial class MockWeatherService : WeatherServiceBase
      {
      
        public override GetForcastResponse GetForcast(GetForcastRequest request) { 
        if (request == null)
          throw new FaultException<GetForcastFault>(new GetForcastFault(), "Request was null.");
          return new GetForcastResponse(); }
      
        public override GetCurrentTemperatureResponse GetCurrentTemperature(GetCurrentTemperatureRequest request) { 
        if (request == null)
          throw new FaultException<GetCurrentTemperatureFault>(new GetCurrentTemperatureFault(), "Request was null.");
          return new GetCurrentTemperatureResponse(); }
      
        public override GetTemperatureHistoryResponse GetTemperatureHistory(GetTemperatureHistoryRequest request) { 
        if (request == null)
          throw new FaultException<GetTemperatureHistoryFault>(new GetTemperatureHistoryFault(), "Request was null.");
          return new GetTemperatureHistoryResponse(); }
      
      }
      public abstract partial class WeatherServiceBase : IWeatherService
      {
      #region Section for dealing with aspects.
      private IList<WeatherServiceAspect>   aspects = null;
      private IList<WeatherServiceAspect>
      Aspects
      {
        get {
          if (aspects == null)
          {
            aspects = new List<WeatherServiceAspect>();
            foreach (var aspect in GetType().GetCustomAttributes(typeof(WeatherServiceAspect), true))
            aspects.Add((aspect as WeatherServiceAspect));
          }
          return aspects.OrderBy(a=>a.Order).ToList(); 
        }
      }
      #endregion
      public event WeatherServiceRequestHandler PreWeatherServiceOperation;
      public event WeatherServiceResponseHandler PostWeatherServiceOperation;
      public event WeatherServiceErrorHandler WeatherServiceOperationError;
      
        public event GetForcastRequestHandler PreGetForcast;
        public event GetForcastResponseHandler PostGetForcast;
        public event GetForcastErrorHandler GetForcastError;
      
        public event GetCurrentTemperatureRequestHandler PreGetCurrentTemperature;
        public event GetCurrentTemperatureResponseHandler PostGetCurrentTemperature;
        public event GetCurrentTemperatureErrorHandler GetCurrentTemperatureError;
      
        public event GetTemperatureHistoryRequestHandler PreGetTemperatureHistory;
        public event GetTemperatureHistoryResponseHandler PostGetTemperatureHistory;
        public event GetTemperatureHistoryErrorHandler GetTemperatureHistoryError;
      
      public delegate void WeatherServiceRequestHandler(ref WeatherServiceRequest request);
      public delegate void WeatherServiceResponseHandler(ref WeatherServiceRequest request, ref WeatherServiceResponse response);
      public delegate void WeatherServiceErrorHandler(ref WeatherServiceRequest request, ref Exception exception);
      
        public delegate void GetForcastRequestHandler(ref GetForcastRequest request);
        public delegate void GetForcastResponseHandler(ref GetForcastRequest request, ref GetForcastResponse response);
        public delegate void GetForcastErrorHandler(ref GetForcastRequest request, ref Exception exception);
      
        public delegate void GetCurrentTemperatureRequestHandler(ref GetCurrentTemperatureRequest request);
        public delegate void GetCurrentTemperatureResponseHandler(ref GetCurrentTemperatureRequest request, ref GetCurrentTemperatureResponse response);
        public delegate void GetCurrentTemperatureErrorHandler(ref GetCurrentTemperatureRequest request, ref Exception exception);
      
        public delegate void GetTemperatureHistoryRequestHandler(ref GetTemperatureHistoryRequest request);
        public delegate void GetTemperatureHistoryResponseHandler(ref GetTemperatureHistoryRequest request, ref GetTemperatureHistoryResponse response);
        public delegate void GetTemperatureHistoryErrorHandler(ref GetTemperatureHistoryRequest request, ref Exception exception);
      
      protected void RaisePreWeatherServiceOperation(WeatherServiceRequest request) {
        foreach (var aspect in Aspects)
        aspect.OnPreWeatherServiceOperation(ref request);
        if (PreWeatherServiceOperation != null) PreWeatherServiceOperation(ref request); }
      protected void RaisePostWeatherServiceOperation(WeatherServiceRequest request, WeatherServiceResponse response) {
        foreach (var aspect in Aspects)
        aspect.OnPostWeatherServiceOperation(ref request, ref response);
        if (PostWeatherServiceOperation != null) PostWeatherServiceOperation(ref request, ref response); }
      protected void RaiseWeatherServiceOperationError(WeatherServiceRequest request, Exception exception) {
        foreach (var aspect in Aspects)
        aspect.OnWeatherServiceOperationError(ref request, ref exception);
        if (WeatherServiceOperationError != null) WeatherServiceOperationError(ref request, ref exception); }
      
      protected void RaisePreGetForcast(GetForcastRequest request) {
        if (PreGetForcast != null) PreGetForcast(ref request); }
      protected void RaisePostGetForcast(GetForcastRequest request, GetForcastResponse response) {
        if (PostGetForcast != null) PostGetForcast(ref request, ref response); }
      protected void RaiseGetForcastError(GetForcastRequest request, Exception exception) {
        if (GetForcastError != null) GetForcastError(ref request, ref exception); }
      
      protected void RaisePreGetCurrentTemperature(GetCurrentTemperatureRequest request) {
        if (PreGetCurrentTemperature != null) PreGetCurrentTemperature(ref request); }
      protected void RaisePostGetCurrentTemperature(GetCurrentTemperatureRequest request, GetCurrentTemperatureResponse response) {
        if (PostGetCurrentTemperature != null) PostGetCurrentTemperature(ref request, ref response); }
      protected void RaiseGetCurrentTemperatureError(GetCurrentTemperatureRequest request, Exception exception) {
        if (GetCurrentTemperatureError != null) GetCurrentTemperatureError(ref request, ref exception); }
      
      protected void RaisePreGetTemperatureHistory(GetTemperatureHistoryRequest request) {
        if (PreGetTemperatureHistory != null) PreGetTemperatureHistory(ref request); }
      protected void RaisePostGetTemperatureHistory(GetTemperatureHistoryRequest request, GetTemperatureHistoryResponse response) {
        if (PostGetTemperatureHistory != null) PostGetTemperatureHistory(ref request, ref response); }
      protected void RaiseGetTemperatureHistoryError(GetTemperatureHistoryRequest request, Exception exception) {
        if (GetTemperatureHistoryError != null) GetTemperatureHistoryError(ref request, ref exception); }
      
        public abstract GetForcastResponse GetForcast(GetForcastRequest request);
      
        public abstract GetCurrentTemperatureResponse GetCurrentTemperature(GetCurrentTemperatureRequest request);
      
        public abstract GetTemperatureHistoryResponse GetTemperatureHistory(GetTemperatureHistoryRequest request);
      GetForcastResponse  IWeatherService.GetForcast(GetForcastRequest request) {
        GetForcastResponse response = null;
        try {
        
        RaisePreWeatherServiceOperation(request);
        RaisePreGetForcast(request);
        response = GetForcast(request);
        RaisePostGetForcast(request, response);
        RaisePostWeatherServiceOperation(request, response);
        
        return response;  }
        catch (Exception exception) {
          
          // Fire OperationException event.
          if (WeatherServiceOperationError == null) throw;
          RaiseWeatherServiceOperationError(request, exception);
          RaiseGetForcastError(request, exception); }
        return response; }
      GetCurrentTemperatureResponse  IWeatherService.GetCurrentTemperature(GetCurrentTemperatureRequest request) {
        GetCurrentTemperatureResponse response = null;
        try {
        
        RaisePreWeatherServiceOperation(request);
        RaisePreGetCurrentTemperature(request);
        response = GetCurrentTemperature(request);
        RaisePostGetCurrentTemperature(request, response);
        RaisePostWeatherServiceOperation(request, response);
        
        return response;  }
        catch (Exception exception) {
          
          // Fire OperationException event.
          if (WeatherServiceOperationError == null) throw;
          RaiseWeatherServiceOperationError(request, exception);
          RaiseGetCurrentTemperatureError(request, exception); }
        return response; }
      GetTemperatureHistoryResponse  IWeatherService.GetTemperatureHistory(GetTemperatureHistoryRequest request) {
        GetTemperatureHistoryResponse response = null;
        try {
        
        RaisePreWeatherServiceOperation(request);
        RaisePreGetTemperatureHistory(request);
        response = GetTemperatureHistory(request);
        RaisePostGetTemperatureHistory(request, response);
        RaisePostWeatherServiceOperation(request, response);
        
        return response;  }
        catch (Exception exception) {
          
          // Fire OperationException event.
          if (WeatherServiceOperationError == null) throw;
          RaiseWeatherServiceOperationError(request, exception);
          RaiseGetTemperatureHistoryError(request, exception); }
        return response; }
       }
      
      public class BatchWeatherService : IBatchWeatherService
      {
      private readonly IWeatherService service;
      private readonly int maxDegreeOfParallelism;
      public BatchWeatherService(IWeatherService service, int maxDegreeOfParallelism = 10) {
        this.service = service;
        this.maxDegreeOfParallelism = maxDegreeOfParallelism; }
      private readonly BatchWeatherServiceResponse response = new BatchWeatherServiceResponse {
        Responses = new ConcurrentDictionary<string, WeatherServiceResponse>(),
        Faults = new ConcurrentDictionary<string, WeatherServiceFault>() };

      public BatchWeatherServiceResponse Process(BatchWeatherServiceRequest request) {
        Parallel.ForEach(request.Requests, new ParallelOptions {
          MaxDegreeOfParallelism = maxDegreeOfParallelism },
          ProcessRequest);
           return response; }
           
      private void ProcessRequest(KeyValuePair<string, WeatherServiceRequest> keyValuePair) {
      try
      {
      
        if (keyValuePair.Value is GetForcastRequest)
        response.Responses.Add(keyValuePair.Key, service.GetForcast(keyValuePair.Value as GetForcastRequest));
      
        if (keyValuePair.Value is GetCurrentTemperatureRequest)
        response.Responses.Add(keyValuePair.Key, service.GetCurrentTemperature(keyValuePair.Value as GetCurrentTemperatureRequest));
      
        if (keyValuePair.Value is GetTemperatureHistoryRequest)
        response.Responses.Add(keyValuePair.Key, service.GetTemperatureHistory(keyValuePair.Value as GetTemperatureHistoryRequest));
      
      }
      catch(FaultException<WeatherServiceFault> fault)
      {
      
        if (fault.Detail is GetForcastFault)
        response.Faults.Add(keyValuePair.Key, fault.Detail as GetForcastFault);
      
        if (fault.Detail is GetCurrentTemperatureFault)
        response.Faults.Add(keyValuePair.Key, fault.Detail as GetCurrentTemperatureFault);
      
        if (fault.Detail is GetTemperatureHistoryFault)
        response.Faults.Add(keyValuePair.Key, fault.Detail as GetTemperatureHistoryFault);
      
      }
      }
      }

      public partial class WeatherServiceProxy : ClientBase<IWeatherService>, IWeatherService
      {
      
        public GetForcastResponse GetForcast(GetForcastRequest request)
        {
        return Channel.GetForcast(request);
        }
      
        public GetCurrentTemperatureResponse GetCurrentTemperature(GetCurrentTemperatureRequest request)
        {
        return Channel.GetCurrentTemperature(request);
        }
      
        public GetTemperatureHistoryResponse GetTemperatureHistory(GetTemperatureHistoryRequest request)
        {
        return Channel.GetTemperatureHistory(request);
        }
      
      }

      public class BatchWeatherServiceProxy : ClientBase<IBatchWeatherService>, IBatchWeatherService
        {
        
          public delegate void GetForcastResponseHandler(GetForcastRequest request, GetForcastResponse response);
          public delegate void GetForcastFaultHandler(GetForcastRequest request, GetForcastFault fault);
          public event GetForcastResponseHandler GetForcastResponse;
          public event GetForcastFaultHandler GetForcastFault;
        
          public delegate void GetCurrentTemperatureResponseHandler(GetCurrentTemperatureRequest request, GetCurrentTemperatureResponse response);
          public delegate void GetCurrentTemperatureFaultHandler(GetCurrentTemperatureRequest request, GetCurrentTemperatureFault fault);
          public event GetCurrentTemperatureResponseHandler GetCurrentTemperatureResponse;
          public event GetCurrentTemperatureFaultHandler GetCurrentTemperatureFault;
        
          public delegate void GetTemperatureHistoryResponseHandler(GetTemperatureHistoryRequest request, GetTemperatureHistoryResponse response);
          public delegate void GetTemperatureHistoryFaultHandler(GetTemperatureHistoryRequest request, GetTemperatureHistoryFault fault);
          public event GetTemperatureHistoryResponseHandler GetTemperatureHistoryResponse;
          public event GetTemperatureHistoryFaultHandler GetTemperatureHistoryFault;
        

        public BatchWeatherServiceResponse Process(BatchWeatherServiceRequest request) { return Channel.Process(request); }

        public void Process(IList<WeatherServiceRequest> requests) { ThreadPool.QueueUserWorkItem(Process, requests); }

        public void Process(object obj)
        {
        var requests = obj as IList<WeatherServiceRequest>;
        IDictionary<WeatherServiceRequest, WeatherServiceResponse> responses;
        IDictionary<WeatherServiceRequest, WeatherServiceFault> faults;
        Process(requests, out responses, out faults);
        foreach (var item in responses) {
        
          if (item.Key is GetForcastRequest)
          GetForcastResponse(item.Key as GetForcastRequest, item.Value as GetForcastResponse);
        
          if (item.Key is GetCurrentTemperatureRequest)
          GetCurrentTemperatureResponse(item.Key as GetCurrentTemperatureRequest, item.Value as GetCurrentTemperatureResponse);
        
          if (item.Key is GetTemperatureHistoryRequest)
          GetTemperatureHistoryResponse(item.Key as GetTemperatureHistoryRequest, item.Value as GetTemperatureHistoryResponse);
         }

        foreach (var item in faults) {
        
          if (item.Key is GetForcastRequest)
          GetForcastFault(item.Key as GetForcastRequest, item.Value as GetForcastFault);
        
          if (item.Key is GetCurrentTemperatureRequest)
          GetCurrentTemperatureFault(item.Key as GetCurrentTemperatureRequest, item.Value as GetCurrentTemperatureFault);
        
          if (item.Key is GetTemperatureHistoryRequest)
          GetTemperatureHistoryFault(item.Key as GetTemperatureHistoryRequest, item.Value as GetTemperatureHistoryFault);
         }
        }

        public void Process(
        IList<WeatherServiceRequest> requests,
        out IDictionary<WeatherServiceRequest, WeatherServiceResponse> responses,
        out IDictionary<WeatherServiceRequest, WeatherServiceFault> faults )
        {
        var requestDictionary = requests.ToDictionary(request => Guid.NewGuid().ToString());
        var processResponse = Process(new BatchWeatherServiceRequest
        {
        Requests = requestDictionary
        });
        responses = (from resp in processResponse.Responses
        join req in requestDictionary
        on resp.Key equals req.Key
        select new { Request = req.Value, Response = resp.Value })
        .ToDictionary(k => k.Request, v => v.Response);

        faults = (from fault in processResponse.Faults
        join req in requestDictionary
        on fault.Key equals req.Key
        select new { Request = req.Value, Fault = fault.Value })
        .ToDictionary(k => k.Request, v => v.Fault);
        }
        }

      }

      namespace Clients
      {
      public partial class WeatherServiceClient : IWeatherServiceClient
        {
          public WeatherServiceClient(IWeatherService service) { Service = service; }
          public IWeatherService Service { get; set; }
        }
    }
  }
    
  
  
    
      
      
      
    
  
  
